package com.wuwei.elearning.setting.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wuwei.elearning.setting.domain.User;
import com.wuwei.elearning.setting.mapper.UserMapper;
import com.wuwei.elearning.setting.service.UserService;
import com.wuwei.elearning.utils.MD5Util;
import com.wuwei.elearning.utils.result.Result;
import com.wuwei.elearning.utils.token.TokenCache;
import com.wuwei.elearning.utils.token.TokenUtil;
import com.wuwei.elearning.vo.PasswordVo;
import com.wuwei.elearning.vo.UserVo;
import com.wuwei.elearning.websocket.WebSocketServer;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@RestController
@RequestMapping(value="/elearning/user")
@CrossOrigin
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private TokenUtil tokenUtil;

    /**
     * 获取实时在线人数
     */
    /*
         String oldPassword = passwordVo.getOldPassword();
        oldPassword = MD5Util.getMD5(oldPassword);
        String newPassword = passwordVo.getNewPassword();
        newPassword = MD5Util.getMD5(newPassword);
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        //验证旧密码
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account).eq(User::getPassword,oldPassword);
        if (userMapper.selectOne(queryWrapper)!=null) {
            //修改新密码
            User user = new User();
            return  userService.setPassword(user,account,newPassword);

        } else{
            Result<String> fail = Result.fail("密码修改失败，旧密码错误！");
            fail.setMessage("密码修改失败，旧密码错误！");
            return fail;
        }
     */
    @GetMapping("/getOnLineCount")
    public Result<List<UserVo>> getOnLineCount(){
        List<UserVo> users = new ArrayList<>();
        CopyOnWriteArraySet<WebSocketServer> webSocketSet = WebSocketServer.getWebSocketSet();
        for (WebSocketServer webSocketServer : webSocketSet) {
            Long account = webSocketServer.getSid();
            UserVo  uservo = userMapper.getInfoFromAccount(account);
            users.add(uservo);
        }
        //对users按照userVo的id去重
        Map<Long, UserVo> uniqueUsers = new HashMap<>();
        for (UserVo user : users) {
            uniqueUsers.put(user.getId(), user);
        }
        users = new ArrayList<>(uniqueUsers.values());

        return Result.ok(users);
    }

    /**
     * 用户登录后，返回给用户一个token,通过用户名称获取的token会被放到缓存中
     * @return
     */
    @PostMapping("login")
    public Result<String> login (@RequestBody User user)

    {
        String password = user.getPassword();
        Long account = user.getAccount();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        String md5 = MD5Util.getMD5(password);
        queryWrapper.eq(User::getAccount,account).eq(User::getPassword,md5);
        User selectOne = userMapper.selectOne(queryWrapper);
        if (selectOne!=null){
            String token = TokenUtil.generateToken(selectOne.getAccount());
            // 这里需要将token存放在内存中
            TokenCache.putToken(account,token);
            return Result.ok(token);
        } else {
            return Result.fail("账号或密码错误!");
        }

    }


    /**
     * 用户通过token，拿到相关信息
     * @return
     */
    @GetMapping("info")
    public Result<User> getUserInfo(@RequestParam("token") String token) {
        User user = userService.getUserInfo(token);
        return Result.ok(user);
    }



    /**
     * 退出登录，这里要销毁本地存储的token
     * @return
     */
    @PostMapping("logout")
    public Result<String> logout (@RequestParam String token){
        Long account = TokenUtil.getAccountFromToken(token);
        TokenCache.removeToken(account);
        return Result.ok("退出登录成功");
    }

    /**
     * 注册用户，这里只有管理员能注册用户，注册的时候会在拦截器验证一下token，所以不需要做判断，直接注册就可以
     * @return
     */
    @PostMapping("regesiter")
    public Result<String> regesiter (@RequestBody User user,HttpServletRequest request){
        String token = request.getHeader("Authorization");
        Long createdBy = TokenUtil.getAccountFromToken(token);
        Long account = user.getAccount();
        userService.regesiter(user,createdBy,account);
        return Result.ok("新用户注册成功！");
    }

    /**
     * 修改密码
     * @return
     */
    @PostMapping("setPassword")
    public Result<String> setPassword (@RequestBody PasswordVo passwordVo, HttpServletRequest request) {
        String oldPassword = passwordVo.getOldPassword();
        oldPassword = MD5Util.getMD5(oldPassword);
        String newPassword = passwordVo.getNewPassword();
        newPassword = MD5Util.getMD5(newPassword);
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        //验证旧密码
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account).eq(User::getPassword,oldPassword);
        if (userMapper.selectOne(queryWrapper)!=null) {
            //修改新密码
            User user = new User();
            return  userService.setPassword(user,account,newPassword);

        } else{
            Result<String> fail = Result.fail("密码修改失败，旧密码错误！");
            fail.setMessage("密码修改失败，旧密码错误！");
            return fail;
        }
    }

    @PutMapping("updateName/{name}")
    public Result<String> updateName(@PathVariable("name")String name, HttpServletRequest request){
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account);
        User user = userMapper.selectOne(queryWrapper);
        user.setName(name);
        userMapper.updateById(user);
        return Result.ok("修改成功！");

    }

    /**
     * 分页查询用户信息列表
     * @param name
     * @param account
     * @param currentPage
     * @param pageSize
     * @param request
     * @return
     */
    @GetMapping("list/{name}/{account}/{currentPage}/{pageSize}")
    public Result<List<User>> list(@PathVariable("name") String name,@PathVariable("account") Long account,
    @PathVariable("currentPage") Integer currentPage,@PathVariable("pageSize") Integer pageSize,HttpServletRequest request){
        //根据用户的等级来获取不同的用户信息，如果用户是教师，则只能获取学生的用户信息，如果用户是管理员，则可以获取所有人的用户信息
        String token = request.getHeader("Authorization");
        Long account1 = TokenUtil.getAccountFromToken(token);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account1);
        User user = userMapper.selectOne(queryWrapper);
        Integer status = user.getStatus();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        List<User> list = new ArrayList<>();
        //如果用户状态是0.代表是管理员，如果是1，代表是教师,如果是2，则返回空
        if (status==2) {
            return Result.ok(list);
        }
        else if (status==0) {
            wrapper.like(account!=0,User::getAccount,account).like(!"_".equals(name),User::getName,name);
        }
        else {
            wrapper.eq(User::getStatus,2).like(account!=0,User::getAccount,account).like(!"_".equals(name),User::getName,name);
        }
        IPage<User> page = new Page<>();
        page.setSize(pageSize);
        page.setCurrent(currentPage);
        IPage<User> userIPage = userMapper.selectPage(page, wrapper);
        list = userIPage.getRecords();
        return Result.ok(list);
    }

    /**
     * 分页查询用户信息列表
     * @param name
     * @param account
     * @param request
     * @return
     */
    @GetMapping("getTotal/{name}/{account}")
    public Result<Long> getTotal(@PathVariable("name") String name,@PathVariable("account") Long account, HttpServletRequest request){
        //根据用户的等级来获取不同的用户信息，如果用户是教师，则只能获取学生的用户信息，如果用户是管理员，则可以获取所有人的用户信息
        String token = request.getHeader("Authorization");
        Long account1 = TokenUtil.getAccountFromToken(token);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account1);
        User user = userMapper.selectOne(queryWrapper);
        Integer status = user.getStatus();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        //如果用户状态是0.代表是管理员，如果是1，代表是教师,如果是2，则返回空
        if (status==2) {
            return Result.ok(0L);
        }
        else if (status==0) {
            wrapper.like(account!=0,User::getAccount,account).like(!"_".equals(name),User::getName,name);
        }
        else {
            wrapper.eq(User::getStatus,2).like(account!=0,User::getAccount,account).like(!"_".equals(name),User::getName,name);
        }
        Long count = userMapper.selectCount(wrapper);
        return Result.ok(count);
    }


    /**
     * 删除用户信息的方法，除了删除user表，还要删除test_answers表和test_result表
     * @param id
     * @return
     */
    @DeleteMapping("delete/{id}")
    public Result<String> delete(@PathVariable("id")Long id){
        /**
         * id为2的用户信息不允许删除
         */
        if (id==1) {
            return Result.fail("超级管理员不允许删除！");
        }
        userService.myDelete(id);
        return Result.ok("删除成功！");
    }

    @PutMapping("resetPassword/{id}/{password}")
    public Result<String> resetPassword(@PathVariable("id") Long id,@PathVariable("password") String password, HttpServletRequest request){
        if (id==1) {
            return Result.fail("超级管理员密码默认为111111且不允许修改！");
        }
        User user = userMapper.selectById(id);
        String md5 = MD5Util.getMD5(password);
        user.setPassword(md5);
        String token = request.getHeader("Authorization");
        Long account1 = TokenUtil.getAccountFromToken(token);
        LocalDateTime now = LocalDateTime.now();
        user.setUpdatedTime(now);
        user.setEditBy(account1);
        userMapper.updateById(user);
        return Result.ok("重置成功！");
    }

    @PostMapping("update")
    public Result<String> update(@RequestBody User user,HttpServletRequest request){
        if (user.getId()==1) {
            return Result.fail("超级管理员权限不得修改！");
        }
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        userService.update(account,user);
        return Result.ok("更新成功");
    }

    /**
     * 查询没有设置班级信息的学员
     * @return
     */
    @GetMapping("getStudents")
    public Result<List<Map<String,Object>>> getStudents(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getStatus,2);
        List<User> users = userMapper.selectList(wrapper);
        List<Map<String,Object>> list = new ArrayList<>();
        users.forEach(u->{
            Map<String,Object> map = new HashMap<>();
            map.put("id", u.getId());
            map.put("name",u.getName());
            list.add(map);
        });
        return Result.ok(list);
    }

    @GetMapping("getTeachers")
    public Result<List<User>> getTeachers(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getStatus,1);
        List<User> users = userMapper.selectList(wrapper);
        return Result.ok(users);
    }

    @GetMapping("getAllStudents")
    public Result<List<User>> getAllStudents(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getStatus,2);
        List<User> users = userMapper.selectList(wrapper);
        return Result.ok(users);
    }

    /**
     * 查询设置了班级信息的学员
     * @param gradeId
     * @return
     */
    @GetMapping("getByGradeId/{gradeId}")
    public Result<List<Long>> getByGradeId(@PathVariable("gradeId") Long gradeId){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getGradeId,gradeId);
        List<User> users = userMapper.selectList(wrapper);
        List<Long> list = new ArrayList<>();
        users.forEach(u->{
            list.add(u.getId());
        });

        return Result.ok(list);
    }



    @PostMapping("uploadAvatar")
    public Result<String> uploadAvatar(MultipartFile file, HttpServletRequest request, @RequestParam("token") String token) {
        String url = userService.uploadAvator(file,token);
        return Result.ok(url);
    }

//
//    /**
//     * 销毁用户的时候设定超级管理员的账户不可销毁
//     * @param id
//     * @return
//     * @throws SaveException
//     */
//    @RequestMapping("/user/destory.do")
//    @ResponseBody
//    public Object destory (String id) throws SaveException {
//        Message message = new Message();
//        //判断如果是超级管理员，则不能销毁该用户
//        if ("23523545345".equals(id)){//23523545345是ww在t_user表里的主键
//            message.setSuccess(false);
//            message.setMessage("超级管理员账户不可销毁！");
//        }
//        else {
//            message = userService.delete(id);
//        }
//        return message;
//    }
}
